package com.vivek.guess.what.calculator;

import static com.vivz.guess.what.util.GuessWhatUtil.getDifferenceAgainstGuess;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.vivz.guess.what.type.Position;
import com.vivz.guess.what.vo.Clue;
import com.vivz.guess.what.vo.Guess;
import com.vivz.guess.what.vo.ProbabilityMatrix;

/**
 * <pre>
 * 3. Check for the definite insiders with their probable positions
 * 
 * Check all the guessed words' weights that match the regex : [.]+ against the zero weights.
 * 
 * Use case #1: you have .'s = valid diff betn 0-weight word and guess-word
 * KING ----
 * GRIT ..
 * .R.T valid diff (Here you know for sure that the position of R and T is definitely NOT 2 and 4 respectively)
 * 
 * Use case #2: you have .'s > diff betn 0-weight word and guess-word
 * KING ----
 * WILD ..
 * W.LD valid diff (Here you know for sure that the position of W, L and T is definitely NOT 1, 3 and 4 respectively)
 * 
 * Use case #3: you have .'s < diff betn 0-weight word and guess-word [NOT POSSIBLE]
 * (Possible when the opponent is a human and has probably given a wrong weighted clue)
 * KING ----
 * RING ..
 * R... valid diff
 * 
 * </pre>
 */
public class ZeroPlus0Calculator extends AbstractCalculator {

	@Override
	public void calculate(final List<Guess> guesses, final ProbabilityMatrix pMatrix) {

		for (final Guess zeroWtGuess : guesses) {
			final Clue zero = zeroWtGuess.getClue();
			if (zero.hasDash()) {
				for (final Guess g : guesses) {
					final Clue clue = g.getClue();
					if (!clue.hasCrosses() && clue.hasDots()) {
						final Map<Character, Position> difference = getDifferenceAgainstGuess(g, zeroWtGuess);
						if (difference.isEmpty()) {
							/* This is one of the possibilities in the Use case #3 - boo hoo */
						} else {
							final int diff = difference.size();
							final int count0 = clue.getCount0();
							final boolean confirmed = diff == count0;

							if (diff >= count0) {
								// This is the Use case #1
								for (final Entry<Character, Position> entry : difference.entrySet()) {
									final Character c = entry.getKey();
									final Position p = entry.getValue();
									pMatrix.markOnlyImpossiblePosition(c, p, confirmed);
								}
							} else {
								// This is one of the possibilities in the Use case #3 - boo hoo
							}
						}
					}
				}
			}
		} // end for
	}

}
